package hibatis.support.generator;

import hibatis.HibatisAutoConfig;
import hibatis.annotation.GeneratedSql;
import hibatis.ext.InterceptorContext;
import hibatis.support.Reflection;
import hibatis.support.parse.EntityMeta;
import org.apache.ibatis.mapping.BoundSql;
import org.apache.ibatis.mapping.SqlSource;
import org.apache.ibatis.reflection.ParamNameResolver;
import org.apache.ibatis.scripting.xmltags.XMLLanguageDriver;
import org.apache.ibatis.session.Configuration;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.lang.reflect.Method;

/**
 * Created by huangdachao on 2018/6/14 16:59.
 */
public class DeleteGenerator {
    private static final Logger LOG = LoggerFactory.getLogger(DeleteGenerator.class);

    public static SqlSource generate(Configuration conf, Class<?> mapperClass, Method method) {
        EntityMeta em = EntityMeta.get(Reflection.getEntityClass(mapperClass));

        return parameterObject -> {
            Object[] args = Reflection.parseArgs(conf, method, parameterObject);
            InterceptorContext context = new InterceptorContext(mapperClass, em.getEntityClass(), method, args, GeneratedSql.Type.DELETE);
            HibatisAutoConfig.intercept(context);

            StringBuilder sql = new StringBuilder("<script>delete t0 ");
            String[] argNames = new ParamNameResolver(conf, method).getNames();
            FromAndWhereGenerator faw = new FromAndWhereGenerator(em, method, args, argNames, context);
            sql.append(faw.generate());
            sql.append("</script>");

            String sqlStr = sql.toString();
            LOG.debug(sqlStr);
            Class<?> parameterType = parameterObject == null ? Object.class : parameterObject.getClass();
            SqlSource sqlSource = conf.getLanguageRegistry().getDriver(XMLLanguageDriver.class)
                .createSqlSource(conf, sqlStr, parameterType);
            BoundSql bsql = sqlSource.getBoundSql(parameterObject);
            faw.getAdditionalParams().forEach(bsql::setAdditionalParameter);
            return bsql;
        };
    }
}
